iT邦幫忙

2024 iThome 鐵人賽

DAY 20
0

Day20 sql練習悲觀鎖

今天來用 sql 實際體會一下悲觀鎖

一樣先reference一下原文(其實原文寫得更濃縮,如果希望一次吸收多一點歡迎直接看原文也是鐵人賽)

先開一個sql editor出來

先看一下當前事物隔離等級

SHOW VARIABLES LIKE 'transaction_isolation';
---'transaction_isolation', 'REPEATABLE-READ'

REPEATABLE-READ 是MySQL的預設事物隔離級別,關於事物隔離級別有四個,可以先簡單想成自動管理鎖的行為,例如 select for update 之後,可不可以讀寫,會讀寫到什麼數據,會根據設定的隔離級別來自動有不同的管理方式,目的就是避免資料不一致,但可能又會想說,那為什麼不用最嚴格的隔離級別,既然有四個等級,因為越嚴格的隔離級別,效能最低(併發量最低,畢竟鎖越多,併發數就越低)

先來直接邊做lab邊了解悲觀鎖,事物隔離後面會有篇幅來專門介紹

以下是準備資料

CREATE TABLE orders (
	`id` INT NOT NULL AUTO_INCREMENT,
	`name` VARCHAR(45) NOT NULL,
	`num` INT NOT NULL,
	PRIMARY KEY (`id`)
);
INSERT INTO orders (`name`,`num`)
VALUES ("iphone",1);

以下會開兩個 session ( sql editor畫面,像我是一個 mysql, 一個 dbeaver,也有看過別人是開兩個 terminal 分別連線到 mysql 裡面指令一個一個輸入,個人推薦開兩個 GUI 做 )

A session

begin;

select num from orders where id = 1 for update;

B session

begin;

select num from orders where id = 1 for update;

此時會發現 B session 卡住,感覺像有一個無限迴圈卡著等待,因為目前 id=1 這一個 row 被鎖住了,這個叫做行鎖(所以也還會有表鎖或是全局鎖),就是把一行資料鎖住不讓其他人更動,除非當前解鎖。

接著
A session

update orders set num = 0 where id = 1;

commit;

這時候 B就可以 select 到值了為0,這樣就不會結帳下去了,避免了超賣。實務上自己也還沒用程式做過,只有看文章下sql實驗機制,不過鎖的觀念應該是通用的,這偏就做這個悲觀鎖小練習!

下面一篇來做樂觀鎖


上一篇
Day19 悲觀樂觀鎖
系列文
我獨自升級之資料庫從入門到中階20
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言